/**
*	@file Utility.h
*
*	@brief this header file is for some utility function
*
*	@author li yuchen
*
*	@date 1/28/2011
*/

#ifndef UTILITY_H
#define UTILITY_H

#include "TNode.h"
#include "QueryThread.h"
#include <queue>
#include <stack>
#include <sstream>
#include <string>
#include <ppl.h>
using namespace Concurrency;
using namespace std;

extern vector<int> concurrency_counter;

/** @brief check whether text is a digit */
bool IsDigit(char text);
/** @brief check whether text is "a-z","A-Z" */
bool IsCharacter(char text);
/** @brief return true if text is either digit or text */
bool IsText(char text);
/** @brief retrieve the precedence of the operator */
int GetPrecedence(TNode* op);
/** @brief for debuging purpose of a expression with an expression of constants */
int EvalueExpr(TNode* root);
/** @brief return the number of cpu for this computer */
int GetNumCPUs();

/* -------------------------------------------------------Set Operation ----------------------------------------------------- */

template <typename BoolSet>
inline BoolSet LogicAND(BoolSet& set_1, BoolSet& set_2)
{
	BoolSet* set_result = new BoolSet;
	set_result->resize(set_1.size());

	for( unsigned int i = 0; i < set_result->size(); i++ )
	{
		set_result->at(i) = set_1[i] & set_2[i];
	}
	return (*set_result);
};

template <typename BoolSet>
inline BoolSet LogicOR(BoolSet& set_1, BoolSet& set_2)
{
	BoolSet* set_result = new BoolSet;
	set_result->resize(set_1.size());

	for( unsigned int i = 0; i < set_result->size(); i++ )
	{
		set_result->at(i) = set_1[i] | set_2[i];
	}
	return (*set_result);
};

template <typename BoolSet>
inline BoolSet LogicMinus(BoolSet& set_1, BoolSet& set_2)
{
	BoolSet* set_result = new BoolSet;
	set_result->resize(set_1.size());

	for( unsigned int i = 0; i < set_result->size(); i++ )
	{
		if( set_1[i] && !set_2[i] )
		set_result->at(i) = true;
	}
	return (*set_result);
};

/** @brief returns whether none of the bits in the set are true. */
template <typename BoolSet>
inline bool IsNone(BoolSet set)
{
	for( unsigned int i = 0; i < set.size(); i++ )
		if( set[i] ) return false;
	return true;
};

/** @brief returns whether any of the bits in the set is true.*/
template <typename BoolSet>
inline bool IsAny(BoolSet set)
{
	for( unsigned int i = 0; i < set.size(); i++ )
		if( set[i] ) return true;
	return false;
};

/** @brief returns whether all of the bits in the set are true. */
template <typename BoolSet>
inline bool IsAll(BoolSet set)
{
	for( unsigned int i = 0; i < set.size(); i++ )
		if( !set[i] ) return false;
	return true;
};

class ErrorLocker{
public:
	inline static void	reset_b_parse_error()	{ b_parse_error_ = false; };
	inline static void	set_b_parse_error()		{ b_parse_error_ = true; };
	inline static bool	get_b_parse_error()		{ return b_parse_error_; };

	inline static void	reset_b_query_error()	{ b_query_error_ = false; };
	inline static void	set_b_query_error()		{ b_query_error_ = true; };
	inline static bool	get_b_query_error()		{ return b_query_error_; };

	inline static void	reset_s_error_message()						{ s_error_message_ = ""; };
	inline static void	set_s_error_message(string error_message)	{ s_error_message_ = error_message; };
	inline static string	get_s_error_message()					{ return s_error_message_; };

private:
	static	bool	b_parse_error_;
	static	bool	b_query_error_;
	static	string	s_error_message_;
};

#endif